package com.icloud.cer.rest.msg;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import com.icloud.cer.rest.Constants;

public class DataFilterOutputStream extends FilterOutputStream {

	protected int writtenLength;
	
	private byte writeBuffer[] = new byte[8];
	
	public DataFilterOutputStream(OutputStream out) {
		super(out);
	}

	private void increaseCount(int value) {
		int temp = writtenLength + value;
		if (temp < 0) {
			temp = Integer.MAX_VALUE;
		}
		writtenLength = temp;
    }
	
	public synchronized void write(int b) throws IOException {
		out.write(b);
		increaseCount(1);
	}
	
    public synchronized void write(byte b[], int off, int len) throws IOException {
		out.write(b, off, len);
		increaseCount(len);
    }
    
    public void flush() throws IOException {
    	out.flush();
    }
    
    public final void writeBoolean(boolean v) throws IOException {
		out.write(v ? 1 : 0);
		increaseCount(1);
	}
    
    public final void writeByte(int v) throws IOException {
    	out.write(v);
    	increaseCount(1);
    }
    
    public final void writeShort(int v) throws IOException {
    	if(Constants.BY_BIG){
            out.write((v >>> 8) & 0xFF);
            out.write((v >>> 0) & 0xFF);
    	}else{
    		out.write((v >>> 0) & 0xFF);
            out.write((v >>> 8) & 0xFF);
    	}
    	increaseCount(2);
    }
    
    public final void writeInt(int v) throws IOException {
    	if(Constants.BY_BIG){
    		out.write((v >>> 24) & 0xFF);
    		out.write((v >>> 16) & 0xFF);
    		out.write((v >>>  8) & 0xFF);
    		out.write((v >>>  0) & 0xFF);
    	}else{
    		out.write((v >>>  0) & 0xFF);
    		out.write((v >>>  8) & 0xFF);
    		out.write((v >>> 16) & 0xFF);
    		out.write((v >>> 24) & 0xFF);
    	}
    	increaseCount(4);
    }
    
    public final void writeLong(long v) throws IOException {
    	if(Constants.BY_BIG){//高位在前
    		writeBuffer[0] = (byte)(v >>> 56);
            writeBuffer[1] = (byte)(v >>> 48);
            writeBuffer[2] = (byte)(v >>> 40);
            writeBuffer[3] = (byte)(v >>> 32);
            writeBuffer[4] = (byte)(v >>> 24);
            writeBuffer[5] = (byte)(v >>> 16);
            writeBuffer[6] = (byte)(v >>>  8);
            writeBuffer[7] = (byte)(v >>>  0);
    	}else{
    		writeBuffer[7] = (byte)(v >>> 56);
    		writeBuffer[6] = (byte)(v >>> 48);
    		writeBuffer[5] = (byte)(v >>> 40);
    		writeBuffer[4] = (byte)(v >>> 32);
    		writeBuffer[3] = (byte)(v >>> 24);
    		writeBuffer[2] = (byte)(v >>> 16);
    		writeBuffer[1] = (byte)(v >>>  8);
    		writeBuffer[0] = (byte)(v >>>  0);
    	}
    	out.write(writeBuffer, 0, 8);
    	increaseCount(8);
    }
    
    public final void writeFloat(float v) throws IOException {
    	writeInt(Float.floatToIntBits(v));
    }
    
    public final void writeDouble(double v) throws IOException {
    	writeLong(Double.doubleToLongBits(v));
    }
    
    public final void writeBytes(String s) throws IOException {
    	int len = s.length();
    	for (int i = 0 ; i < len ; i++) {
    	    out.write((byte)s.charAt(i));
    	}
    	increaseCount(len);
    }
    
    public final int size() {
    	return writtenLength;
    }
}
